package com.shouxue.dragrvdemo;

import android.animation.AnimatorSet;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntRange;
import androidx.annotation.StringRes;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.res.ResourcesCompat;
import java.util.Random;

/**
 * @author COT, uidq5175
 * Time: 2022-8-5 17:39
 * Description:textView和switch组合的跑马灯效果switch
 * <p>
 * Copyright (c) 2022 Desaysv All rights reserved.
 */
public class MarqueeSwitch extends ConstraintLayout
        implements View.OnClickListener, View.OnLongClickListener {

    private static final String TAG = MarqueeSwitch.class.getSimpleName();

    /**
     * 不可用的mode值
     */
    public static final int DISABLE_MODE = 100;
    /**
     * 拖拽时的透明度
     */
    private static final float ALPHA = 0.7F;

    /**
     * 图标
     */
    private ImageView mIcon;
    /**
     * 文本
     */
    private MarqueeText mTextView;
    /**
     * 编辑按钮
     */
    private ImageView ivEdit;
    /**
     * 右上角小三角图标
     */
    private ImageView ivTriangle;

    /**
     * 选中后字体颜色
     */
    private int textColorSelect;
    /**
     * 默认未选中字体颜色
     */
    private int textColor;
    /**
     * 默认未选中字体颜色
     */
    private int textDisableColor;
    /**
     * 选中状态
     * 0 未选中
     * 1选中
     * 2~max 为多选状态
     */
    private int mode = 0;
    /**
     * 默认最大选中状态 状态最大值，若大于1，则从最小值开始循环切换
     */
    private int maxMode = 1;

    /**
     * 是否从1开始循环，默认从0开始
     */
    private boolean isMin = false;
    /**
     * 是否显示小三角
     */
    private boolean isShowTriangle = false;

    /**
     * 是否为编辑状态
     */
    private boolean isEdit = false;
    private boolean isDrag;
    /**
     * 复合动画
     */
    private AnimatorSet mAnimatorSet;

    private Context mContext;

    private OnClickListener onClickListener;//单击
    private OnLongClickListener onLongClickListener;//长按

    public MarqueeSwitch(Context context) {
        this(context, null);
    }

    public MarqueeSwitch(Context context, AttributeSet attributeSet) {
        this(context, attributeSet, 0);
    }

    public MarqueeSwitch(Context context, AttributeSet attributeSet, int i) {
        super(context, attributeSet, i);
        this.mContext = context;

        init(attributeSet);
    }

    /**
     * 从XML中获取自定义属性,初始化控件
     */
    private void init(AttributeSet attributeSet) {
        TypedArray array = mContext.obtainStyledAttributes(attributeSet, R.styleable.MarqueeSwitch);
        LayoutInflater.from(mContext).inflate(R.layout.layout_view_marquee_switch_drag, this, true);

        mIcon = findViewById(R.id.iv_marquee_icon);
        mTextView = findViewById(R.id.tv_marquee_content);
        ivEdit = findViewById(R.id.iv_marquee_edit);
        ivTriangle = findViewById(R.id.iv_marquee_triangle);

//        int drawable = array.getResourceId(R.styleable.MarqueeSwitch_drawable, R.drawable.selector_bt);
        int text = array.getResourceId(R.styleable.MarqueeSwitch_text, R.string.app_name);
        textColor = array.getColor(R.styleable.MarqueeSwitch_text_color, Color.WHITE);
        textColorSelect = array.getColor(R.styleable.MarqueeSwitch_text_color_select, Color.WHITE);
        textDisableColor = array.getColor(R.styleable.MarqueeSwitch_text_disable_color, mContext.getColor(R.color.white_30));
        float leftTextMargin = array.getDimension(R.styleable.MarqueeSwitch_left_margin, 0);
        float topDrawableMargin = array.getDimension(R.styleable.MarqueeSwitch_top_drawable_margin, 0);
        boolean focusable = array.getBoolean(R.styleable.MarqueeSwitch_focusable, true);
        array.recycle();

        setClipChildren(false);

//        mIcon.setImageDrawable(ResourcesCompat.getDrawable(mContext.getResources(), drawable, null));
        mTextView.setText(text);
        mTextView.setTextColor(textColor);
//        if (0 != leftTextMargin) {
//            LayoutParams layoutParams = (LayoutParams) mTextView.getLayoutParams();
//            layoutParams.leftMargin = (int) leftTextMargin;
//            mTextView.setLayoutParams(layoutParams);
//        }
//        if (0 != topDrawableMargin) {
//            LayoutParams layoutParams = (LayoutParams) mIcon.getLayoutParams();
//            layoutParams.leftMargin = (int) topDrawableMargin;
//            mIcon.setLayoutParams(layoutParams);
//        }
        if (focusable) {
            setOnClickListener(this);
        } else {
            //去除按键音
            setClickable(false);
        }

        setSelect(getMin());

        //生成随机方向晃动的动画
        int random = new Random().nextInt(2);
        random = random > 0 ? 1 : -1;
        Log.d(TAG, "init: rotateShakeAnimation random = " + random);
        //频率和幅度是根据客户输入的
        mAnimatorSet = AnimationUtil.rotateShakeAnimation(this, 3, 4F * random);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
                Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
        super.dispatchDraw(canvas);
    }

    /**
     * 状态切换 循环
     */
    public void looper() {
        Log.d(TAG, "looper: mode ".concat(String.valueOf(mode))
                .concat(" ,maxMode ").concat(String.valueOf(maxMode))
                .concat(" ,name ").concat(String.valueOf(mTextView.getText())));
        mIcon.setImageLevel(mode);
        mTextView.setTextColor(getMin() != mode ? textColorSelect : textColor);
    }

    /**
     * 获取当前mode
     */
    public int getMode() {
        return mode;
    }

    /**
     * 设置多行显示，若为单行，则为跑马灯效果
     *
     * @param maxLines 文本行数
     */
    public MarqueeSwitch setMaxLines(int maxLines) {
        if (1 == maxLines) {
            mTextView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
        } else {
            mTextView.setEllipsize(TextUtils.TruncateAt.END);
        }
        mTextView.setSingleLine(1 == maxLines);
        mTextView.setMaxLines(maxLines);
        return this;
    }

    /**
     * 设置文本
     */
    public MarqueeSwitch setText(String string) {
        mTextView.setText(string);
        return this;
    }

    /**
     * 设置文本
     */
    public MarqueeSwitch setText(@StringRes int stringRes) {
        mTextView.setText(getContext().getText(stringRes));
        return this;
    }

    public String getText() {
        if (null == mTextView) {
            return "";
        }
        return String.valueOf(mTextView.getText());
    }

    /**
     * 设置图片与父布局的边界，也就是icon一半的高度
     */
    public MarqueeSwitch setIconMarginTop(int top) {
        LayoutParams params = (LayoutParams) mIcon.getLayoutParams();
        params.topMargin = top;
        mIcon.setLayoutParams(params);
        return this;
    }

    /**
     * 设置选中时的颜色
     */
    public MarqueeSwitch setTextSelectColor(@ColorInt int color) {
        textColorSelect = color;
        mTextView.setTextColor(color);
        return this;
    }

    /**
     * 设置未选中时的颜色
     */
    public MarqueeSwitch setTextColor(int color) {
        Log.d(TAG, "setTextColor: " + color);
        textColor = color;
        mTextView.setTextColor(color);
        return this;
    }

    /**
     * 设置不可用颜色
     */
    public MarqueeSwitch setTextDisableColor(@ColorInt int color) {
        textDisableColor = color;
        mTextView.setTextColor(color);
        return this;
    }

    /**
     * 是否显示小三角
     */
    public MarqueeSwitch setShowTriangle(boolean isShow) {
        //todo 功能移除
//        this.isShowTriangle = isShow;
//        ivTriangle.setVisibility(isShow ? VISIBLE : GONE);
        return this;

    }

    /**
     * 获取最大状态值
     */
    public int getMaxMode() {
        return maxMode;
    }

    /**
     * 设置最大状态
     */
    public MarqueeSwitch setMaxMode(@IntRange(from = 0) int maxMode) {
        return this.setMaxMode(maxMode, false);
    }

    /**
     * 设置状态最大值
     *
     * @param maxMode 最大状态
     * @param isFirst 是否从1开始循环
     */
    public MarqueeSwitch setMaxMode(@IntRange(from = 0) int maxMode, boolean isFirst) {
        this.maxMode = maxMode;
        return setMin(isFirst);
    }

    public MarqueeSwitch setMin(boolean min) {
        isMin = min;
        return this;
    }

    /**
     * 获取循环是否从1开始
     */
    public int getMin() {
        return isMin ? 1 : 0;
    }

    /**
     * 设置选中
     */
    public MarqueeSwitch setSelect(@IntRange(from = 0) int mode) {
        Log.d(TAG, "setSelect: mode " + mode + " min = " + getMin() + " title = " + mTextView.getText().toString());
        //若在编辑状态下，阻止更新选中
        if (isEdit) {
            mTextView.setTextColor(textColor);
            return this;
        }
        this.mode = mode;
        mIcon.setImageLevel(mode);
        mTextView.setTextColor(getMin() != mode ? textColorSelect : textColor);
        return this;
    }

    /**
     * 是否被选中
     */
    public boolean isSelect() {
        return mode > 0;
    }

    /**
     * 设置图片
     */
    public MarqueeSwitch setDrawables(Drawable drawable) {
        mIcon.setImageDrawable(drawable);
        return this;
    }

    /**
     * 设置图片
     */
    public MarqueeSwitch setDrawables(@DrawableRes int idRes) {
        mIcon.setImageDrawable(ResourcesCompat.getDrawable(mContext.getResources(), idRes, null));
        return this;
    }

    /**
     * 根据编辑模式设置icon
     */
    public MarqueeSwitch setEditMode(boolean isEdit, boolean isAdd) {
        this.isEdit = isEdit;
        ivEdit.setVisibility(isEdit ? VISIBLE : INVISIBLE);
        if (isEdit) {
            ivEdit.setImageDrawable(ResourcesCompat.getDrawable(mContext.getResources(),
                    isAdd ? R.mipmap.icon_edit_delete : R.mipmap.icon_edit_add, null));
            ivTriangle.setVisibility(GONE);

            startAnimation();
        } else {
            ivTriangle.setVisibility(isShowTriangle ? VISIBLE : GONE);

            endAnimation();
        }
        return this;
    }

    /**
     * 设置拖拽模式，拖拽时隐藏加减图标
     *
     * @param isDrag true 正在拖拽
     */
    public MarqueeSwitch setDragMode(boolean isDrag) {
        this.isDrag = isDrag;
        ivEdit.setVisibility(isDrag ? INVISIBLE : VISIBLE);
        return this;
    }

    public boolean isDragMode() {
        return isDrag;
    }

    /**
     * 开始执行晃动动画
     */
    public void startAnimation() {
        if (null == mAnimatorSet) {
            Log.e(TAG, "endAnimation: mAnimatorSet is null");
            return;
        }
        //开启硬件加速
        setLayerType(View.LAYER_TYPE_HARDWARE, new Paint());
        //执行旋转晃动动画
        mAnimatorSet.start();
    }

    /**
     * 结束执行晃动动画
     */
    public void endAnimation() {
        if (null == mAnimatorSet) {
            Log.e(TAG, "endAnimation: mAnimatorSet is null");
            return;
        }
        //关闭晃动动画
        mAnimatorSet.end();

        //执行归位
        setRotation(0);

        //关闭硬件加速 关闭会出现锯齿
        //setLayerType(View.LAYER_TYPE_NONE, new Paint());
    }

    /**
     * 不可用时（置灰状态）
     */
    public MarqueeSwitch setDisableMode(boolean isDisabled) {
        //2024.06.24 t26车型未添加的快捷方式背景不置灰
        if (isDisabled) {
            mTextView.setTextColor(textDisableColor);
            mIcon.setImageLevel(DISABLE_MODE);
        } else {
            mTextView.setTextColor(textColor);
            mIcon.setImageLevel(getMin());
        }
        return this;
    }

    /**
     * 设置是否可点击
     */
    public MarqueeSwitch setSwitchClickable(boolean isEnable) {
        setClickable(isEnable);
        setLongClickable(isEnable);

        //setDisableAnimal(!isEnable);
        Log.d(TAG, "setSwitchClickable: " + mIcon + ", clickable = " + mIcon.isClickable());
        return this;
    }

    /**
     * 若不可用，则执行透明状态
     *
     * @param isDisable true 表示不可用
     */
    public MarqueeSwitch setDisableAnimal(boolean isDisable) {
        Log.d(TAG, "setDisableAnimal: isDisable = [" + isDisable + "]");
        if (isDisable) {
            setAlpha(0.5F);
        } else {
            setAlpha(1);
        }
        return this;
    }

    /**
     * 是否按压
     */
    @Override
    public boolean isPressed() {
        return mIcon.isPressed() || mTextView.isPressed();
    }

    /**
     * 长按
     */
    public MarqueeSwitch addOnLongClickListener(OnLongClickListener onLongClickListener) {
        this.onLongClickListener = onLongClickListener;

        setOnLongClickListener(this);
        return this;
    }

    /**
     * 移除长按
     */
    public void removeOnLongClickListener() {
        this.onLongClickListener = null;
    }

    /**
     * 设置监听
     */
    public MarqueeSwitch addOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
        return this;
    }

    /**
     * 移除监听
     */
    public void removeOnClickListener() {
        this.onClickListener = null;
    }

    /**
     * 设置子view透明度，不包含文本
     */
    private void setItemAlpha(float alpha) {
        mIcon.setAlpha(alpha);
        ivEdit.setAlpha(alpha);
        ivTriangle.setAlpha(alpha);
    }

    @Override
    protected void onDetachedFromWindow() {
        Log.d(TAG, "cot : onDetachedFromWindow");
        if (null != mAnimatorSet) {
            mAnimatorSet.cancel();
            mAnimatorSet.removeAllListeners();
        }
        super.onDetachedFromWindow();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_POINTER_UP:
            default:
                setItemAlpha(1);
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                setItemAlpha(ALPHA);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_POINTER_UP:
            default:
                setItemAlpha(1);
                break;
        }
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public void onClick(View v) {
        if (null != onClickListener) {
            if (onClickListener.onClick(mode)) {
                // looper();
            }
        }
    }

    @Override
    public boolean onLongClick(View v) {
        if (null != onLongClickListener) {
            onLongClickListener.onLongClick(v, mode);
            return true;//不执行onClick
        }
        return false;
    }

    public interface OnClickListener {
        boolean onClick(int mode);
    }

    public interface OnLongClickListener {
        void onLongClick(View view, int mode);
    }
}

